package com.viroyal.monitorlib;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hwangjr.rxbus.RxBus;
import com.suntiago.baseui.utils.log.Slog;
import com.viroyal.monitorlib.core.DownloadConfig;
import com.viroyal.monitorlib.core.DownloadManager;
import com.viroyal.monitorlib.entity.AppInfo;
import com.viroyal.monitorlib.entity.DownloadEntry;
import com.viroyal.monitorlib.entity.rx.RxAppUpdate;
import com.viroyal.monitorlib.entity.rx.RxDownloadUpdate;
import com.viroyal.monitorlib.network.Api;
import com.viroyal.monitorlib.network.UpdateApi;
import com.viroyal.monitorlib.network.req.AppsResponse;
import com.viroyal.monitorlib.notify.DataChanger;
import com.viroyal.monitorlib.notify.DataWatcher;
import com.viroyal.monitorlib.utils.AppUtils;
import com.viroyal.monitorlib.utils.Constants;
import com.viroyal.monitorlib.utils.SPUtils;
import com.viroyal.monitorlib.utils.ToastMgr;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by zy on 2017/11/13.
 */

public class AppModel {

    private static final String TAG = "AppModel";

    //后台配置的数据，桌面需要去控制显示，升级的时候不需要匹配
    private List<AppInfo> appInfoList = new ArrayList<>();

    private final static String ALL_APP_KEY = "ALL_APP_KEY";
    private Context mContext;

    private static AppModel sAppModel;

    public static AppModel get() {
        if (sAppModel == null) {
            sAppModel = new AppModel();
        }
        return sAppModel;
    }


    //读取本地缓存数据
    public static void init(Context context) {
        get().mContext = context;
        get().readDb();
        get().dataChanger = DataChanger.getInstance(get().mContext);
    }

    //更新数据
    private void update() {

    }

    public List<AppInfo> getAllApps() {
        return appInfoList;
    }

    public AppInfo getApp(AppInfo a) {
        if (appInfoList != null && appInfoList.size() > 0) {
            for (AppInfo appInfo : appInfoList) {
                if (appInfo.getPackageNmae().equals(a.getPackageNmae())) {
                    return appInfo;
                }
            }
        }
        return null;
    }


    //从网络加载数据
    public void loadApps() {
        Api.get().getApi(UpdateApi.class).getApps(Api.get().getSchoolId())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<AppsResponse>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(AppsResponse appsResponse) {
                        if (appsResponse.error_code == 1000) {
                            if (appsResponse.appsExtra.apk_list != null && appInfoList != null) {
                                Log.d(TAG, "call  [appsResponse]:apk_list " +
                                        appsResponse.appsExtra.apk_list.toString() +
                                        " appInfoList " + appInfoList.toString());
                                if (appsResponse.appsExtra.apk_list.toString().equals(appInfoList.toString())) {
                                    Log.d(TAG, "call  [appsResponse]:" + "无需更新数据");
//                                    checkIfUpdate();
                                    return;
                                }
                            }
                            appInfoList = appsResponse.appsExtra.apk_list;
//                            checkIfUpdate();
                        } else {
                            Slog.d(TAG, "checkUpdate onNext  [appsResponse]:");
                        }
                    }
                });
    }

    //检测是否需要更新
    private void checkIfUpdate() {
        for (AppInfo appInfo : appInfoList) {
            PackageInfo info = AppUtils.getPackageInfo(mContext, appInfo.packageNmae);
            if (info == null) {
                Slog.d("checkUpdate", "checkUpdate  [没有安装]:" + appInfo.getName());
                if (TextUtils.isEmpty(appInfo.apk_url)) {
                    appInfo.setStatus(0);
                    Slog.d(TAG, "checkUpdate: apk update url is null");
                } else {
                    appInfo.setStatus(-1);

                    //startDownload(appInfo.apk_url);
                }
            } else {
                Slog.d("checkUpdate", "checkUpdate  [appInfo.version_code , info.versionCode]:" + appInfo.version_code + " " + info.versionCode);
                if (appInfo.version_code > info.versionCode) {
                    Log.d("checkUpdate", "checkUpdate  [需要升级]:" + appInfo.getName());
                    if (TextUtils.isEmpty(appInfo.apk_url)) {
                        Slog.d(TAG, "checkUpdate: apk update url is null");
                        appInfo.setStatus(1);
                    } else {
                        appInfo.setStatus(1);

                        //     startDownload(appInfo.apk_url);
                    }
                } else {
                    appInfo.setStatus(0);
                    Slog.d("checkUpdate", "checkUpdate  [不用动]:" + appInfo.getName());
                    if (appInfo.getName().contains("课堂教学")) {
                        startApplicationUninstallActivity(appInfo);
                    }
                }
            }
        }
        writeDb();

        RxBus.get().post(RxAppUpdate.build().reset());
    }

    private void writeDb() {
        Gson g = new Gson();
        String s = g.toJson(appInfoList, new TypeToken<ArrayList<AppInfo>>() {
        }.getType());
        SPUtils.getInstance(mContext).put(ALL_APP_KEY, s);
    }

    private void readDb() {
        String all = SPUtils.getInstance(mContext).get(ALL_APP_KEY);
        if (TextUtils.isEmpty(all)) {
            return;
        } else {
            appInfoList.clear();
            Gson g = new Gson();
            List<AppInfo> a = g.fromJson(all, new TypeToken<ArrayList<AppInfo>>() {
            }.getType());
            appInfoList.addAll(a);
        }
    }

    // returns true if the activity was started
    boolean startApplicationUninstallActivity(AppInfo appInfo) {
        Slog.d(TAG, "startApplicationUninstallActivity  [appInfo]:" + appInfo.getPackageNmae());
        String packageName = appInfo.getPackageNmae();
        Intent intent = new Intent(
                Intent.ACTION_DELETE, Uri.fromParts("package", packageName, null));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        mContext.startActivity(intent);
        return true;
    }

    public void uninstall(String packageName) {
        Intent intent = new Intent(
                Intent.ACTION_DELETE, Uri.fromParts("package", packageName, null));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        mContext.startActivity(intent);
    }


    public void install(AppInfo appInfo) {
        Slog.d(TAG, "install  [appInfo]:");

        File savePath = new File(DownloadConfig.DOWNLOAD_PATH);
        if (!savePath.exists()) {
            return;
        }
        File file = new File(savePath, appInfo.apk_url.substring(
                appInfo.apk_url.lastIndexOf("/") + 1));
        RxBus.get().post(file);
//        if (AppUtils.isAccessibilitySettingsOn(mContext)) {
//            Slog.d(TAG, "handleMessage  [msg]: auto install");
            install(file.getPath());
//        } else {
//            install(file.getPath());
//            Slog.d(TAG, "handleMessage  [msg]: no auto install");
//        }

    }

    public void download(AppInfo appInfo) {
        Slog.d(TAG, "download  [appInfo]:");
        startDownload(appInfo);
    }

    public void download(String url, String pkgName) {
        Slog.d(TAG, "startDownload  [appInfo]:");
        SPUtils.getInstance(mContext).put(Constants.APK_URL, url);
        SPUtils.getInstance(mContext).put(Constants.OTHER_APK_URL, url);
        DownloadEntry entry = getEntry(url);
        entry.pkg_name = pkgName;
        DownloadManager.getInstance(mContext).add(entry);
        DownloadManager.getInstance(mContext).addObserver(dataWatcher);
    }

    private void startDownload(AppInfo appInfo) {

        AppInfo a = getApp(appInfo);
        if (a == null) {
            return;
        }
        Slog.d(TAG, "startDownload  [appInfo]:");
        String url = appInfo.apk_url;
        SPUtils.getInstance(mContext).put(Constants.APK_URL, url);
        DownloadEntry entry = getEntry(url);
        DownloadManager.getInstance(mContext).add(entry);
        DownloadManager.getInstance(mContext).addObserver(dataWatcher);
    }

    private DataWatcher dataWatcher = new DataWatcher() {

        @Override
        public void onDataChanged(DownloadEntry data) {
            Slog.d(TAG, "onDataChanged  [data]:" + "正在下载" + data.percent + "%");
            RxBus.get().post(RxAppUpdate.build().loaddetails());
            RxBus.get().post(new RxDownloadUpdate(data.percent, data.pkg_name));
            ToastMgr.builder.display("正在下载" + data.percent + "%", Toast.LENGTH_SHORT);
        }
    };

    private DataChanger dataChanger;

    public DownloadEntry getEntry(String url) {
        DownloadEntry entry;
        if (dataChanger.containsDownloadEntry(url)) {
            entry = dataChanger.queryDownloadEntryByUrl(url);
        } else {
            entry = new DownloadEntry(url);
            entry.name = url.substring(url.lastIndexOf("/") + 1);//apk名字
        }
        return entry;
    }

    public void install(String apkPath) {
        File file = new File(apkPath);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= 24) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            //参数1：上下文，参数2：Provider主机地址和mainfest中配置的一致，参数3：共享的文件
            Uri contentUri = FileProvider.getUriForFile(mContext, AppUtils.getPackageName(mContext) + ".fileprovider"
                    , file);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            //不在activity中启动activity开启新的任务栈
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        mContext.startActivity(intent);
    }
}
